<?php

namespace App\Service\OpenShop\Feishu;

use App\Enums\Check\CheckEnum;
use App\Models\OpenShop\InvestmentPromotion\OpenShopLocationModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrderTagsMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Remote\Orm\OrmNewOrderRemote;
use App\Remote\Rms\RmsShopRemote;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Cache;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use function Symfony\Component\Translation\t;

class KfosService
{
    // delivery_note.status
    const DELIVERY_NOTE_STATUS_CREATED   = 1;
    const DELIVERY_NOTE_STATUS_CONFIRMED = 2;
    const DELIVERY_NOTE_STATUS_DELIVERED = 3;
    const DELIVERY_NOTE_STATUS_RECEIVED  = 4;
    const DELIVERY_NOTE_STATUS_FINISHED  = 5;
    const DELIVERY_NOTE_STATUS_CLOSED    = 6;

    const DELIVERY_NOTE_STATUS_TEXT = [
        self::DELIVERY_NOTE_STATUS_CREATED   => '已生成',
        self::DELIVERY_NOTE_STATUS_CONFIRMED => '已确认',
        self::DELIVERY_NOTE_STATUS_DELIVERED => '已发货',
        self::DELIVERY_NOTE_STATUS_RECEIVED  => '已收货',
        self::DELIVERY_NOTE_STATUS_FINISHED  => '已完成',
        self::DELIVERY_NOTE_STATUS_CLOSED    => '已关闭',
    ];

    // new_order.status
    const NEW_ORDER_STATUS_PAYING      = 1;
    const NEW_ORDER_STATUS_PAID        = 2;
    const NEW_ORDER_STATUS_FINISHED    = 3;
    const NEW_ORDER_STATUS_CLOSED      = 4;
    const NEW_ORDER_STATUS_STEP_PAYING = 5;

    const NEW_ORDER_STATUSES = [
        self::NEW_ORDER_STATUS_PAYING      => '未支付',
        self::NEW_ORDER_STATUS_PAID        => '进行中',
        self::NEW_ORDER_STATUS_FINISHED    => '已完成',
        self::NEW_ORDER_STATUS_CLOSED      => '已关闭',
        self::NEW_ORDER_STATUS_STEP_PAYING => '分笔支付中',
    ];

    const PAYMENT_STATUS_PAYING      = 1;
    const PAYMENT_STATUS_PAID        = 2;
    const PAYMENT_STATUS_PART_REFUND = 3;
    const PAYMENT_STATUS_FULL_REFUND = 4;
    const PAYMENT_STATUS_PART_PAID   = 5;

    const PAYMENT_STATUSES = [
        self::PAYMENT_STATUS_PAYING      => '未支付',
        self::PAYMENT_STATUS_PAID        => '已支付',
        self::PAYMENT_STATUS_PART_REFUND => '部分退款',
        self::PAYMENT_STATUS_FULL_REFUND => '完全退款',
        self::PAYMENT_STATUS_PART_PAID   => '分笔支付中',
    ];

    public static function shopIdByOrderNo(string $orderNo): int
    {
        return (int)OpenShopMainProcessModel::query()->where('orderNo', $orderNo)->orderBy('id', 'desc')->value('shopId');
    }

    public static function firstDeliveryNotes(string $orderNo)
    {
        $shopId   = static::shopIdByOrderNo($orderNo);
        $body = OrmNewOrderRemote::newOrderFirstDeliveryNotes($shopId);
        return static::formatDeliveryNotes($body)['list'];
    }


    /**
     * 检查是否有首次订货单
     *
     * @param int $shopId
     * @return bool
     * @throws GuzzleException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function checkHasFirstDeliveryNotes(int $shopId)
    {
        $body = OrmNewOrderRemote::newOrderFirstDeliveryNotes($shopId);

        $list = static::formatDeliveryNotes($body)['list'];

        if (count($list)){
            return true;
        }else{
            return false;
        }
    }

    protected static function formatDeliveryNotes($body)
    {
        $list = collect($body['data']['list'] ?? [])->map(function ($item) {
            return [
                'id'               => $item['deliveryNoteId'],
                'orderCode'        => $item['orderCode'],
                'deliveryNoteCode' => $item['deliveryNoteCode'],
                'totalPrice'       => round(100 * $item['totalPrice']),
                'payPrice'         => round(100 * $item['payPrice']),
                'refundPrice'      => round(100 * $item['refundPrice']),
                'statusText'       => $item['statusText'],
                'payStatusText'    => $item['paymentStatusText'],
                'createdAt'        => $item['create_time'],
                'status'           => $item['status'],
                'orderStatus'      => $item['orderStatus'],
                'goodsNames'       => $item['goodsNames'],
                'supplierName'     => $item['supplierName'],
            ];
        })->toArray();
        $orders = collect($body['data']['orders'] ?? [])->map(function ($item) {
            $item['totalAmount']  = round(100 * ($item['totalAmount'] ?? 0));
            $item['refundAmount'] = round(100 * ($item['refundAmount'] ?? 0));
            $item['payAmount']    = round(100 * ($item['payAmount'] ?? 0));
            return $item;
        })->toArray();
        return compact('list', 'orders');
    }

    public static function equipmentDeliveryNotes(string $orderNo, int $sysType = CheckEnum::SYS_TYPE_OPEN_SHOP_EQUIPMENT)
    {
        $shopId   = static::shopIdByOrderNo($orderNo);
        $body = OrmNewOrderRemote::equipmentDeliveryNotes($shopId, '2099-12-31', $sysType);
        return static::formatDeliveryNotes($body);
    }

    public static function deliveryNoteReceived(string $orderNo, int $deliveryNoteId)
    {
        $body = OrmNewOrderRemote::deliveryNoteReceived($deliveryNoteId);
        $code = $body['code'] ?? null;
        if (0 === $code) {
            return [true, '操作成功'];
        }
        return [false, $body['msg'] ?? '订货系统走丢了'];

    }

    public static function myEquipments(string $orderNo, int $sysType = CheckEnum::SYS_TYPE_OPEN_SHOP_EQUIPMENT)
    {
        $order = OpenShopSignOrderModel::query()
            ->where('orderNo', $orderNo)
            ->first();
        if (null === $order) {
            return [];
        }

        $shopId = (int)OpenShopMainProcessModel::query()->where('orderNo', $orderNo)->orderBy('id', 'desc')->value('shopId');
        if (!$shopId) {
            return [];
        }

        $arr = OrmNewOrderRemote::myEquipments($shopId, $sysType);
        return $arr['data']['list'] ?? [];
    }

    /**
     * 预计开店时间
     * @param string $orderNo
     * @return string
     */
    public static function firstDate(string $orderNo)
    {
        $timestamp = Cache::remember('kf_tiger_open_shop_kfos:first_date_' . $orderNo, 60, function ()  use ($orderNo) {
            $startBusiness = OpenShopStartBusinessModel::query()
                ->where('orderNo', $orderNo)
                ->where('step', 1)
                ->value('startBusinessTime');
            if (null === $startBusiness) {
                $startBusiness = OpenShopLocationModel::query()
                    ->where('orderNo', $orderNo)
                    ->where('step', 3)
                    ->value('openTime');
            }
            return $startBusiness;
        });
        if (null === $timestamp) {
            return date('Y-m-d', time() + 86400);
        }
        return date('Y-m-d', $timestamp);
    }

    public static function deliveryNoteDetail(string $orderNo, int $id)
    {
        $data = null;
        $shopId   = static::shopIdByOrderNo($orderNo);
        $arr = OrmNewOrderRemote::deliveryNoteDetail($id, $shopId);
        if (0 !== ($arr['code'] ?? null)) {
            return null;
        }
        if (isset($arr['data']) && is_array($arr['data'])) {
            $data               = $arr['data'];
            $data['totalPrice'] = round(100 * $data['totalPrice']);
            $data['paidPrice']  = round(100 * $data['paidPrice']);
            $data['goods']      = collect($data['goods'])
                ->map(function ($item) {
                    $item['refundPrice']      = round($item['refundPrice'] * 100);
                    $item['singleSalesPrice'] = round($item['singleSalesPrice'] * 100);
                    $item['totalPrice']       = round($item['totalPrice'] * 100);
                    return $item;
                })->toArray();
        }
        return $data;
    }

    public static function workClothesLists(string $orderNo)
    {
        $shopId = KfosService::shopIdByOrderNo($orderNo);
        $body   = OrmNewOrderRemote::equipmentDeliveryNotes($shopId, '2099-12-31', CheckEnum::SYS_TYPE_WORK_CLOTHES);
        return KfosService::formatDeliveryNotes($body);
    }

    public static function createWorkClothes(string $orderNo, array $goods, int $supplierId, int $uid, string $username): string
    {
        $shopId = static::shopIdByOrderNo($orderNo);
        if (!$shopId) {
            \App\Service\BaseService::throwErr("该开店订单未关联门店");
        }

        // 校验供应商
//        $supplierConfig = collect(OrmNewOrderRemote::getWorkClothesGroups()['data']['suppliers'] ?? [])->keyBy('id')[$supplierId] ?? [];
//        if (!$supplierConfig) {
//            \App\Service\BaseService::throwErr("不存在的工服供应商");
//        }

        // 校验商品
//        $goodsConfig = collect($supplierConfig['goods'] ?? [])->keyBy('id');
//        foreach ($goods as $good) {
//            $goodsId  = $good['id'];
////            $goodsNum = $good['num'];
//
//            if (!isset($goodsConfig[$goodsId])) {
//                \App\Service\BaseService::throwErr("当前供应商下不存在该商品:{$goodsId}");
//            }
//        }

        // curl 新增工服订单
        $order = OrmNewOrderRemote::createWorkClothes($shopId, $supplierId, $goods, $uid, $username);
        if (!isset($order['code']) || $order['code'] != 200) {
            \App\Service\BaseService::throwErr($order['msg'] ?? '创建订单失败');
        }

        $newOrderId = $order['data']['id'];

        // 工服标签
        (new ShopTagsService($orderNo))->updateWorkClothes();

        return $newOrderId;
    }

    /**
     * 订货单关闭
     * @param string $orderNo
     * @param int $newOrderId
     * @param int $uid
     * @param string $username
     * @param int $sys_type
     * @return void
     */
    public static function closeNewOrder(string $orderNo, int $newOrderId, int $uid, string $username, int $sys_type = CheckEnum::SYS_TYPE_WORK_CLOTHES)
    {
        $shopId = static::shopIdByOrderNo($orderNo);
        if (!$shopId) {
            \App\Service\BaseService::throwErr("该开店订单未关联门店");
        }

        $orm = OrmNewOrderRemote::closeWorkClothes($newOrderId, $uid, $username, $sys_type);
        if (!isset($orm['code']) || $orm['code'] != 200) {
            \App\Service\BaseService::throwErr($orm['msg'] ?? '关闭订单失败');
        }

        // 工服标签
        if ($sys_type == CheckEnum::SYS_TYPE_WORK_CLOTHES) {
            (new ShopTagsService($orderNo))->updateWorkClothes();
        }

    }

    public static function writeOffWorkClothes(string $orderNo, int $newOrderId)
    {
        $orm = OrmNewOrderRemote::writeOffWorkClothes($newOrderId);
        if (!isset($orm['code']) || $orm['code'] != 200) {
            \App\Service\BaseService::throwErr($orm['msg'] ?? '核销订单失败');
        }
    }

}
